﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Animation;

namespace Emilie.Animation.Simple
{
    public static class Projection
    {
        private static Random r = new Random();

        static void sb_Completed(object sender, object e)
        {
            var s = sender as Storyboard;
            s.Completed -= sb_Completed;
            Base.Unregister(s);
        }

        public static void BeginProjectionX(this FrameworkElement _target, Double? _fX, Double _tX, TimeSpan _duration, EasingFunctionBase _easingMode, StoryboardOptions _options)
        {
            RotateX(_target, _fX, _tX, _duration, _easingMode, _options).Begin();
        }

        public static void BeginProjectionY(this FrameworkElement _target, Double? _fY, Double _tY, TimeSpan _duration, EasingFunctionBase _easingMode, StoryboardOptions _options)
        {
            RotateY(_target, _fY, _tY, _duration, _easingMode, _options).Begin();
        }

        public static void BeginProjectionZ(this FrameworkElement _target, Double? _fZ, Double _tZ, TimeSpan _duration, EasingFunctionBase _easingMode, StoryboardOptions _options)
        {
            RotateZ(_target, _fZ, _tZ, _duration, _easingMode, _options).Begin();
        }

        public static void BeginProjection(this FrameworkElement _target, Double? _fX, Double? _fY, Double? _fZ, Double _tX, Double _tY, Double _tZ, TimeSpan _duration, EasingFunctionBase _easingMode, StoryboardOptions _options)
        {
            Rotate(_target, _fX, _fY, _fZ, _tX, _tY, _tZ, _duration, _easingMode, _options).Begin();
        }

        public static Storyboard RotateX(FrameworkElement _target, Double? _fX, Double _tX, TimeSpan _duration, EasingFunctionBase _easingMode, StoryboardOptions _options)
        {
            Storyboard sb = new Storyboard();                                                               // Create a storyboard
            String ID = Base.GenerateUniqueID();                                                            // Generate a Unique ID for the storyboard
            _target.Resources.Add(ID + "ProjectionAnimation", sb);                                            // Register Storyboard with parent element


            sb.AddDoubleAnimation(_target, TargetProperty.ProjectionRotationX, _tX, _fX, null, _duration, _easingMode);


            // FINALIZE STORYBOARD
            Base.ApplyStoryboardOptions(sb, _options);                                                      // Apply storyboard options
            Base.Register(_target, sb, ID + "ProjectionAnimation");
            //sb.Completed += sb_Completed;

            return sb;
        }

        public static Storyboard RotateY(FrameworkElement _target, Double? _fY, Double _tY, TimeSpan _duration, EasingFunctionBase _easingMode, StoryboardOptions _options)
        {
            Storyboard sb = new Storyboard();                                                               // Create a storyboard
            String ID = Base.GenerateUniqueID();                                                            // Generate a Unique ID for the storyboard
            _target.Resources.Add(ID + "ProjectionAnimation", sb);                                            // Register Storyboard with parent element
            _target.GetPlaneProjection();                                                        // Ensure valid composite transform exists on target

            // CREATE X AXIS ANIMATION
            DoubleAnimation ttY = new DoubleAnimation
            {
                From = _fY,
                To = _tY,
                Duration = new Duration(_duration),
                RepeatBehavior = new RepeatBehavior { Count = 1 },
                EasingFunction = _easingMode
            };

            Storyboard.SetTarget(ttY, _target);
            //Storyboard.SetTargetName(ttY, _target.Name);
            Storyboard.SetTargetProperty(ttY, "(UIElement.Projection).(PlaneProjection.RotationY)");
            sb.Children.Add(ttY);



            // FINALIZE STORYBOARD
            Base.ApplyStoryboardOptions(sb, _options);                                                      // Apply storyboard options
            Base.Register(_target, sb, ID + "ProjectionAnimation");
            //sb.Completed += sb_Completed;



            return sb;
        }

        public static Storyboard RotateZ(FrameworkElement _target, Double? _fZ, Double _tZ, TimeSpan _duration, EasingFunctionBase _easingMode, StoryboardOptions _options)
        {
            Storyboard sb = new Storyboard();                                                               // Create a storyboard
            String ID = Base.GenerateUniqueID();                                                            // Generate a Unique ID for the storyboard
            _target.Resources.Add(ID + "ProjectionAnimation", sb);                                            // Register Storyboard with parent element
            _target.GetPlaneProjection();                                                            // Ensure valid composite transform exists on target

            // CREATE X AXIS ANIMATION
            DoubleAnimation ttZ = new DoubleAnimation
            {
                From = _fZ,
                To = _tZ,
                Duration = new Duration(_duration),
                RepeatBehavior = new RepeatBehavior { Count = 1 },
                EasingFunction = _easingMode
            };

            Storyboard.SetTarget(ttZ, _target);
            //Storyboard.SetTargetName(ttZ, _target.Name);
            Storyboard.SetTargetProperty(ttZ, "(UIElement.Projection).(PlaneProjection.RotationZ)");
            sb.Children.Add(ttZ);



            // FINALIZE STORYBOARD
            Base.ApplyStoryboardOptions(sb, _options);                                                      // Apply storyboard options
            Base.Register(_target, sb, ID + "ProjectionAnimation");
            //sb.Completed += sb_Completed;



            return sb;
        }

        public static Storyboard Rotate(FrameworkElement _target, Double? _fX, Double? _fY, Double? _fZ, Double _tX, Double _tY, Double _tZ, TimeSpan _duration, EasingFunctionBase _easingMode, StoryboardOptions _options)
        {
            Storyboard sb = new Storyboard();                                                               // Create a storyboard
            String ID = Base.GenerateUniqueID();                                                            // Generate a Unique ID for the storyboard
            _target.Resources.Add(ID + "ProjectionAnimation", sb);                                            // Register Storyboard with parent element
            _target.GetPlaneProjection();                                                            // Ensure valid composite transform exists on target

            // CREATE X AXIS ANIMATION
            DoubleAnimation ttX = new DoubleAnimation
            {
                From = _fX,
                To = _tX,
                Duration = new Duration(_duration),
                RepeatBehavior = new RepeatBehavior { Count = 1 },
                EasingFunction = _easingMode
            };

            Storyboard.SetTarget(ttX, _target);
            //Storyboard.SetTargetName(ttX, _target.Name);
            Storyboard.SetTargetProperty(ttX, "(UIElement.Projection).(PlaneProjection.RotationX)");
            sb.Children.Add(ttX);

            // CREATE X AXIS ANIMATION
            DoubleAnimation ttY = new DoubleAnimation
            {
                From = _fY,
                To = _tY,
                Duration = new Duration(_duration),
                RepeatBehavior = new RepeatBehavior { Count = 1 },
                EasingFunction = _easingMode
            };

            Storyboard.SetTarget(ttY, _target);
            //Storyboard.SetTargetName(ttY, _target.Name);
            Storyboard.SetTargetProperty(ttY, "(UIElement.Projection).(PlaneProjection.RotationY)");
            sb.Children.Add(ttY);

            // CREATE X AXIS ANIMATION
            DoubleAnimation ttZ = new DoubleAnimation
            {
                From = _fZ,
                To = _tZ,
                Duration = new Duration(_duration),
                RepeatBehavior = new RepeatBehavior { Count = 1 },
                EasingFunction = _easingMode
            };

            Storyboard.SetTarget(ttZ, _target);
            //Storyboard.SetTargetName(ttZ, _target.Name);
            Storyboard.SetTargetProperty(ttZ, "(UIElement.Projection).(PlaneProjection.RotationZ)");
            sb.Children.Add(ttZ);



            // FINALIZE STORYBOARD
            Base.ApplyStoryboardOptions(sb, _options);                                                      // Apply storyboard options
            Base.Register(_target, sb, ID + "ProjectionAnimation");
            //sb.Completed += sb_Completed;



            return sb;
        }
    }
}
